#ifndef _SMP_LIST_H
#define _SMP_LIST_H

#include "sgl_funcs.h"
#include "sgl_window.h"
#include "res.h"


enum {
	SMP_LIST_SETDATAPROVIDER,
	SMP_LIST_SETDRAWROWCALLBACK,
	SMP_LIST_SETDRAWROWEXCALLBACK,
	//SMP_LIST_DEFAULTDRAWROWCALLBACK,
	SMP_LIST_HILIGHTBYINDEX,
	SMP_LIST_GETHILIGHTINDEX,
	SMP_LIST_GETPAGEINFO,
	SMP_LIST_PAGEUP,
	SMP_LIST_PAGEDOWN,
	SMP_LIST_LINEUP,
	SMP_LIST_LINEDOWN,
	SMP_LIST_REFRESH,
	SMP_LIST_RESET
	,SMP_LIST_SETSHOWMODE
	,SMP_LIST_GETSHOWMODE
	
	,SMP_LIST_SCROLL_START
	,SMP_LIST_SCROLL_STOP
	,SMP_LIST_SCROLL_GETTITLE
	,SMP_LIST_SCROLL_PAUSE
	,SMP_LIST_SCROLL_RESUME
	,SMP_LIST_HILIGHTTOTOP

	,SMP_LIST_SCROLL_ISSTOP
	
	//,SMP_LIST_WNDPROC
};

#ifndef SDK_NO_PLUGIN
#define SMP_LIST_WNDPROC  MPS_CODE_SMP_LIST_PROC
#else
#define SMP_LIST_WNDPROC  SMP_List_WndProc
#endif

/**
  \defgroup smp_list Simple List

  To work with simple list:
  - Create your data provider callbacks
  - Create the simple list
  - Set the list data provider with your callbacks
  - Add to the parent window
  - Response to the notify events

  \code
  int YourListGetTotal(VOID)
  {
  	...
  }

  VOID YourListGetRowData(int index, PSMPROWDATA pRowData)
  {
  	...
  }

  //create the list
  hList = SGL_CreateWindow(SMP_List_WndProc, ...);
  SMP_List_SetDataProvider(hList, YourListGetTotal, YourListGetRowData);
  SGL_AddChildWindow(hWnd, hList);

  //response to the notify messages
	case WM_COMMAND:
		WID id = LOWORD(wParam);
		WORD code = HIWORD(wParam);

		if(id == "the list id")
		{
			int index = (int)lParam; //the selected row index
			switch(code)
			{
			case SMP_LISTN_HILICHANGED:
				break;
			case SMP_LISTN_SELECTED:
				break;
			case SMP_LISTN_CLICKED:
				break;
			}
		}	  
  \endcode
  
  @ingroup controls
  @{
*/

	/**
	* \name Window Styles
	* @{
	*/

/**
 * \brief Indicates the list has no scrollbar.
 */
#define SMP_LISTS_NOSCRBAR			0x0001L

#define SMP_LISTS_CIRCULAR               0x0002L

/**
 * \brief Indicates the list mode is list mode.
 */
#define SMP_LISTS_LIST_MODE		0x0000L

#define SMP_LISTS_BMP_RIGHT        0x0004L
/**
 * \brief Indicates the list mode is icon mode.
 */
#define SMP_LISTS_ICON_MODE		0x0010L
#define SMP_LISTS_DOUBLE_MODE        0x0020L

#define SMP_LISTS_MODE_MASK		0x00f0L
	/** @} */

	/**
	 * \name Window Notify Messages
	 * @{
	 */

/**
 * \brief Sent when high light index changed.
 *
 * \code
 *	case WM_COMMAND:
 *		WID id = LOWORD(wParam);
 *		WORD code = HIWORD(wParam);
 *
 *		if(id == "the list id" && code == SMP_LISTN_HILICHANGED)
 *		{
 *			int index = (int)lParam;
 * 			//handle the notify message
 *		}
 * \endcode
 *
 * \param index current high light index
 */
#define SMP_LISTN_HILICHANGED			0x0001

/**
 * \brief Sent when KEY SELECT up.
 *
 * \code
 *	case WM_COMMAND:
 *		WID id = LOWORD(wParam);
 *		WORD code = HIWORD(wParam);
 *
 *		if(id == "the list id" && code == SMP_LISTN_SELECTED)
 *		{
 *			int index = (int)lParam;
 * 			//handle the notify message
 *		}
 * \endcode
 *
 * \param index current high light index
 */
#define SMP_LISTN_SELECTED			0x0002

/**
 * \brief Sent when MOUSE up.
 *
 * \code
 *	case WM_COMMAND:
 *		WID id = LOWORD(wParam);
 *		WORD code = HIWORD(wParam);
 *
 *		if(id == "the list id" && code == SMP_LISTN_CLICKED)
 *		{
 *			int index = (int)lParam;
 * 			//handle the notify message
 *		}
 * \endcode
 *
 * \param index current high light index
 */
#define SMP_LISTN_CLICKED				0x0003

#define SMP_LISTN_SCROLL_OUT                  0x0004
#define SMP_LIST_OUT_OF_TOP                   0
#define SMP_LIST_OUT_OF_BOTTOM             1

#define SMP_LISTN_MOUSEDOWN 		0x0005
#define SMP_LISTN_MOUSEUP 			0x0006


	/** @} */

/**
 * \brief Max supported collumns.  
 */
#define SMP_LIST_MAX_STR_COL		2

/**
 * \brief Row information.
 */
typedef struct SMP_RowData
{
	HWND hList;
	/** left margin */
	Uint16 margin;
	/** icon col width */
	Uint16 colWidth0;
	/** icon handle */
	//HBITMAP hBmp;
	bmpSt hBmp;
	bmpSt littleIcon;
	uint16 bmpMode;
	/** col information */
	struct{
		/** col string */
		PCWSTR str;
		/** col width */
		Uint16 width;
	}cols[SMP_LIST_MAX_STR_COL];	
}SMPROWDATA, *PSMPROWDATA;

typedef struct ListMouse_Event
{
	int index;
	DWORD itemW;
	DWORD itemH;
	DWORD mouseX;
	DWORD mouseY;
} LISTMOUSE_EVENT;

/**
 * \brief The function provide to list to get total row count.
 *
 * \return the total rows of the list
 */
//typedef int (*SMP_List_GetTotal)(HWND hList);
#ifndef SDK_NO_PLUGIN
typedef int SMP_List_GetTotal;
#else
typedef int32 (*SMP_List_GetTotal)(int32 p0, int32 p1, int32 p2, int32 p3, int32 p4, int32 p5);
#endif

/**
 * \brief The function provide to list to get row data.
 *
 * \param index the row index
 * \param[out] pRowData the row data
 */
//typedef VOID (*SMP_List_GetRowData)(HWND hList, int index, PSMPROWDATA pRowData);
#ifndef SDK_NO_PLUGIN
typedef int SMP_List_GetRowData;
#else
typedef int32 (*SMP_List_GetRowData)(int32 p0, int32 p1, int32 p2, int32 p3, int32 p4, int32 p5);
#endif

/**
 * \brief The draw row function.
 *
 * \param index the row index
 * \param r the r rectangle
 * \param pRowData the row data
 * \param hilight the high light row index
 * \param flush if flush to the screen
 */
typedef VOID (*SMP_List_DrawRow)(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);
//typedef int SMP_List_DrawRow;

//typedef VOID (*SMP_List_DrawRowEx)(HWND hList, int index, PRECT r, int hilight, BOOL flush);
#ifndef SDK_NO_PLUGIN
typedef int SMP_List_DrawRowEx;
#else
typedef int32 (*SMP_List_DrawRowEx)(int32 p0, int32 p1, int32 p2, int32 p3, int32 p4, int32 p5);
#endif
	
	/**
	 * \name Window Member Functions
	 * @{
	 */

#if defined(INCLUDE_IN_PLUG_SGL_SRC) || defined(SDK_NO_PLUGIN)
/**
 * \brief Set list window display mode.
 *
 * \param hList the list window handle
 * \param mode the display mode of list
 */
int32 SMP_List_SetShowMode(HWND hList, DWORD mode);

/**
 * \brief Get list window display mode.
 *
 * \param hList the list window handle
 * \return mode the display mode of list
 */
DWORD SMP_List_GetShowMode(HWND hList);

/**
 * \brief Set user data provide callbacks.
 *
 * \param hList the list window handle
 * \param fnGetTotal the function to get total row count
 * \param fnGetRowData the function to get row data by index that from 0
 */
int32 SMP_List_SetDataProvider(HWND hList, SMP_List_GetTotal fnGetTotal, SMP_List_GetRowData fnGetRowData);

/**
 * \brief Set a user specific drawing function.
 *
 * \param hList the List window handle
 * \param fnDrawRow the new draw row function
 */
int32 SMP_List_SetDrawRowCallback(HWND hList, SMP_List_DrawRow fnDrawRow);

int32 SMP_List_SetDrawRowExCallback(HWND hList, SMP_List_DrawRowEx fnDrawRowEx);
/**
 * \brief The default draw row function.
 *
 * \param index the index of the list item
 * \param r the list item draw rect
 * \param pRowData the row data
 * \param hilight current hilight list item index
 * \param flush if flush to screen
 */
//VOID SMP_List_DefaultDrawRowCallback(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);

/**
 * \brief High light a row by index.
 *
 * \param hList the List window
 * \param index the row index
 */
int32 SMP_List_HilightByIndex(HWND hList, int index);

/**
 * \brief Get current high light row index.
 *
 * \param hList the List window handle
 * \return the row index
 */
int SMP_List_GetHilightIndex(HWND hList);

/**
 * \brief Get the current page start item index and page size.
 *
 * \param hList the list window handle
 * \param[out] pagestart the current page start list item
 * \param[out] pagesize the list page size
 */
int32 SMP_List_GetPageInfo(HWND hList, int* pagestart, int* pagesize);

/**
 * \brief Page up the list.
 *
 * \param hList the list window handle
 */
int32 SMP_List_PageUp(HWND hList);

/**
 * \brief Page down the list. 
 *
 * \param hList the list window handle
 */
int32 SMP_List_PageDown(HWND hList);

/**
 * \brief Line up the list.
 *
 * \param hList the list window handle
 */
int32 SMP_List_LineUp(HWND hList, int step);

/**
 * \brief Line down the list.
 *
 * \param hList the list window handle
 */
int32 SMP_List_LineDown(HWND hList, int step);

/**
 * \brief Notify list that total list items changed.
 *
 * \param hList the list window handle
 */
int32 SMP_List_Refresh(HWND hList);

/**
 * \brief Reset the list.
 * 
 * \param hList the list window handle
 */
int32 SMP_List_Reset(HWND hList);

	/** @} */

	/**
	 * \name Window Procedure
	 * @{
	 */

/**
 * \brief The simple list window procedure.
 *
 * \param hList the window handle
 * \param Msg the window message
 * \param wParam the first parameter
 * \param lParam the second parameter
 * \return the result of message process 
 */
LRESULT SMP_List_WndProc(HWND hList, UINT Msg, WPARAM wParam, LPARAM lParam);

//int32 SMP_List_DefaultDrawRowCallback(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);
void SMP_List_DefaultDrawRowCallback(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);

//int32 SMP_List_DrawIconRowCallback(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);
void SMP_List_DrawIconRowCallback(int index, PRECT r, PSMPROWDATA pRowData, int hilight, BOOL flush);

int32 SMP_List_TitleScroll_Start(HWND hList, int32 hili, PCWSTR title);

int32 SMP_List_TitleScroll_Stop(VOID);

PWSTR SMP_List_TitleScroll_GetTitle(void);
	
int32 SMP_List_TitleScroll_Pause(VOID);

int32 SMP_List_TitleScroll_Resume(VOID);

int32 SMP_List_HilightToTop(HWND hList);

int32 SMP_List_TitleScroll_isStop(HWND hList, int32 hili);
#else
/**
 * \brief Set list window display mode.
 *
 * \param hList the list window handle
 * \param mode the display mode of list
 */
#define SMP_List_SetShowMode(hList, mode) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SETSHOWMODE, (int32)hList, (int32)mode, (int32)0, (int32)0, (int32)0)

/**
 * \brief Get list window display mode.
 *
 * \param hList the list window handle
 * \return mode the display mode of list
 */
#define SMP_List_GetShowMode(hList) \
	(DWORD)mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_GETSHOWMODE, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Set user data provide callbacks.
 *
 * \param hList the list window handle
 * \param fnGetTotal the function to get total row count
 * \param fnGetRowData the function to get row data by index that from 0
 */
#define SMP_List_SetDataProvider(hList, fnGetTotal, fnGetRowData) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SETDATAPROVIDER, (int32)hList, (int32)fnGetTotal, (int32)fnGetRowData, (int32)0, (int32)0)

/**
 * \brief Set a user specific drawing function.
 *
 * \param hList the List window handle
 * \param fnDrawRow the new draw row function
 */
#define SMP_List_SetDrawRowCallback(hList, fnDrawRow) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SETDRAWROWCALLBACK, (int32)hList, (int32)fnDrawRow, (int32)0, (int32)0, (int32)0)

#define SMP_List_SetDrawRowExCallback(hList, fnDrawRowEx) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SETDRAWROWEXCALLBACK, (int32)hList, (int32)fnDrawRowEx, (int32)0, (int32)0, (int32)0)

/**
 * \brief The default draw row function.
 *
 * \param index the index of the list item
 * \param r the list item draw rect
 * \param pRowData the row data
 * \param hilight current hilight list item index
 * \param flush if flush to screen
 */
 /*
#define SMP_List_DefaultDrawRowCallback(index, r, pRowData, hilight, flush) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_DEFAULTDRAWROWCALLBACK, (int32)index, (int32)r, (int32)pRowData, (int32)hilight, (int32)flush)
*/

/**
 * \brief High light a row by index.
 *
 * \param hList the List window
 * \param index the row index
 */
#define SMP_List_HilightByIndex(hList, index) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_HILIGHTBYINDEX, (int32)hList, (int32)index, (int32)0, (int32)0, (int32)0)

/**
 * \brief Get current high light row index.
 *
 * \param hList the List window handle
 * \return the row index
 */
#define SMP_List_GetHilightIndex(hList) \
	(int)mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_GETHILIGHTINDEX, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Get the current page start item index and page size.
 *
 * \param hList the list window handle
 * \param[out] pagestart the current page start list item
 * \param[out] pagesize the list page size
 */
#define SMP_List_GetPageInfo(hList, pagestart, pagesize) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_GETPAGEINFO, (int32)hList, (int32)pagestart, (int32)pagesize, (int32)0, (int32)0)

/**
 * \brief Page up the list.
 *
 * \param hList the list window handle
 */
#define SMP_List_PageUp(hList) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_PAGEUP, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Page down the list. 
 *
 * \param hList the list window handle
 */
#define SMP_List_PageDown(hList) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_PAGEDOWN, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Line up the list.
 *
 * \param hList the list window handle
 */
#define SMP_List_LineUp(hList, step) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_LINEUP, (int32)hList, (int32)step, (int32)0, (int32)0, (int32)0)

/**
 * \brief Line down the list.
 *
 * \param hList the list window handle
 */
#define SMP_List_LineDown(hList, step) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_LINEDOWN, (int32)hList, (int32)step, (int32)0, (int32)0, (int32)0)

/**
 * \brief Notify list that total list items changed.
 *
 * \param hList the list window handle
 */
#define SMP_List_Refresh(hList) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_REFRESH, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Reset the list.
 * 
 * \param hList the list window handle
 */
#define SMP_List_Reset(hList) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_RESET, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

#define SMP_List_TitleScroll_Start(hList, hili, title) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_START, (int32)hList, (int32)hili, (int32)title, (int32)0, (int32)0)
	

#define SMP_List_TitleScroll_Stop() \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_STOP, (int32)0, (int32)0, (int32)0, (int32)0, (int32)0)
	
#define SMP_List_TitleScroll_GetTitle() \
	(PWSTR)mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_GETTITLE, (int32)0, (int32)0, (int32)0, (int32)0, (int32)0)
	
#define SMP_List_TitleScroll_Pause() \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_PAUSE, (int32)0, (int32)0, (int32)0, (int32)0, (int32)0)

#define SMP_List_TitleScroll_Resume() \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_RESUME, (int32)0, (int32)0, (int32)0, (int32)0, (int32)0)

#define SMP_List_HilightToTop(hList) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_HILIGHTTOTOP, (int32)hList, (int32)0, (int32)0, (int32)0, (int32)0)

#define SMP_List_TitleScroll_isStop(hList, hili) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST, SMP_LIST_SCROLL_ISSTOP, (int32)hList, (int32)hili, (int32)0, (int32)0, (int32)0)
	
	/** @} */

	/**
	 * \name Window Procedure
	 * @{
	 */

/**
 * \brief The simple list window procedure.
 *
 * \param hList the window handle
 * \param Msg the window message
 * \param wParam the first parameter
 * \param lParam the second parameter
 * \return the result of message process 
 */
#define SMP_List_WndProc(hList, Msg, wParam, lParam) \
	(LRESULT)mrc_extSendAppEventEx(MPS_CODE_SMP_LIST_PROC, (int32)hList, (int32)Msg, (int32)wParam, (int32)lParam, (int32)0, (int32)0)

#define SMP_List_DefaultDrawRowCallback(index, r, pRowData, hilight, flush) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST_LISTDRAW, (int32)index, (int32)r, (int32)pRowData, (int32)hilight, (int32)flush, (int32)0)


#define SMP_List_DrawIconRowCallback(index, r, pRowData, hilight, flush) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_LIST_ICONDRAW, (int32)index, (int32)r, (int32)pRowData, (int32)hilight, (int32)flush, (int32)0)



#endif
	

	/** @} */

/** @} end of smp_list */

#endif /* _SMP_LIST_H */

